package com.longe.nio.selector;

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class SelectorTest {

    public static void main(String[] args) throws Exception {

        Selector selector = Selector.open();

        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        //设为非阻塞
        serverSocketChannel.configureBlocking(false);
        //绑定端口
        serverSocketChannel.socket().bind(new InetSocketAddress(9999));
        //注册到selector,指定感兴趣的事件为连接就绪
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        System.err.println("监听了端口： " + 9999);


        while (true) {
            int keyNums = selector.select();
            System.err.println("返回key的数量为：" + keyNums);
            if(keyNums > 0){ //有事件要处理
                Set<SelectionKey> selectionKeys = selector.selectedKeys();
                System.err.println("selectionKeys为：" + selectionKeys);

                //获取所有感兴趣的事件
                Iterator<SelectionKey> iterator = selectionKeys.iterator();
                while (iterator.hasNext()) {
                    SelectionKey selectionKey = iterator.next();
                    if(selectionKey.isAcceptable()) { //接收就绪状态
                        //通过key反向来获取Channel
                        ServerSocketChannel serverSocketChannelByKey = (ServerSocketChannel) selectionKey.channel();
                        System.err.println(serverSocketChannelByKey == serverSocketChannel);
                        SocketChannel socketChannel = serverSocketChannelByKey.accept();
                        //设置为非阻塞状态
                        socketChannel.configureBlocking(false);
                        //注册Channel到Selector, 指定感兴趣的事件为读
                        socketChannel.register(selector, SelectionKey.OP_READ);
                        //移除该key, 否则下次迭代还会存在该key
                        iterator.remove();

                        System.err.println("获取客户端连接: " + socketChannel.hashCode());

                    }

                    if(selectionKey.isReadable()) { //读状态
                        //通过key来获取Channel
                        SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
                        //创建buffer
                        ByteBuffer buffer = ByteBuffer.allocate(4);
                        StringBuilder sb = new StringBuilder();
                        int read;
                        while ((read = socketChannel.read(buffer)) > 0) {
                            //把缓存区的数据转成字符串
                            String msg = new String(buffer.array(), 0, read);
                            sb.append(msg);
                            //复位
                            buffer.clear();
                        }
                        //输出该消息
                        System.out.println("form " + socketChannel.hashCode() + " : " + sb.toString());

                        iterator.remove();
                    }


                }
            }
        }

    }
}
